package com.winit.openapi.lma.controller.builder;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.thoughtworks.xstream.mapper.Mapper.Null;
import com.winit.common.spi.context.CommandContext;
import com.winit.oms.spi.lma.command.QueryShipmentOrderBySellerCommand;
import com.winit.oms.spi.lma.vo.LMAShipmentOrderLabelVo;
import com.winit.oms.spi.lma.vo.LMAShipmentOrderMerchandiseVo;
import com.winit.oms.spi.lma.vo.LMAShipmentOrderPackageVo;
import com.winit.oms.spi.lma.vo.LMAShipmentOrderSellerQueryVo;
import com.winit.oms.spi.lma.vo.LMAShipmentOrderVo;
import com.winit.oms.spi.lma.vo.LMAShipmentOrderWorkOrderHelpVo;
import com.winit.oms.spi.outbound.vo.OutboundOrderWorkOrderHelpVo;
import com.winit.oms.spi.vo.EbayOrderVo;
import com.winit.oms.spi.vo.v2.order.BuyerInfo;
import com.winit.oms.spi.vo.v2.order.ProductInfo;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.util.DateUtil;

public class LMAShipmentOrderBuilder {

    /**
     * 创建发货订单
     * 
     * @param json
     * @return
     */
    public static LMAShipmentOrderVo buildCreateShipmentOrder(JSONObject json) {

        LMAShipmentOrderVo shipmentVo = new LMAShipmentOrderVo();
        shipmentVo.setIsRepeat("N");
        /**************************** shipment head ***********************/
        if (json.containsKey("shiperMemo")) {
            shipmentVo.setShiperMemo(StringUtils.trim(json.getString("shiperMemo")));
        }
        if (json.containsKey("shipDate")) {
            shipmentVo.setShipDate(json.getDate("shipDate"));
        }
        if (json.containsKey("totalParcelsNumber")) {
            shipmentVo.setTotalParcelsNumber(json.getInteger("totalParcelsNumber"));
        }
        if (json.containsKey("totalParcelsWeight") && StringUtils.isNotBlank(json.getString("totalParcelsWeight"))) {
            shipmentVo.setTotalParcelsWeight(json.getBigDecimal("totalParcelsWeight").setScale(4,
                BigDecimal.ROUND_HALF_UP));
        }

        /**************************** shipment ProductVo ***********************/
        ProductInfo productInfo = new ProductInfo();
        if (json.containsKey("productInfo")) {
            JSONObject product = (JSONObject) json.getJSONObject("productInfo");
            if (product.containsKey("winitProductCode")) {
                productInfo.setWinitProductCode(StringUtils.trim(product.getString("winitProductCode")));
            }
            shipmentVo.setProductInfo(productInfo);
        }

        /**************************** shipment customerInfo ***********************/
        if (json.containsKey("sellerOrderNo")) {
            shipmentVo.setSellerOrderNo(StringUtils.trim(json.getString("sellerOrderNo")));
        }

        /**************************** shipment EbayOrderVo ***********************/
        EbayOrderVo ebayOrderVo = new EbayOrderVo();
        if (json.containsKey("eBayOrderId")) {
            ebayOrderVo.setEbayOrderNo(StringUtils.trim(json.getString("eBayOrderId")));
        }
        if (json.containsKey("eBaySellerId")) {
            ebayOrderVo.setEbaySellerId(StringUtils.trim(json.getString("eBaySellerId")));
        }
        if (json.containsKey("eBayBuyerId")) {
            ebayOrderVo.setEbayBuyerId(StringUtils.trim(json.getString("eBayBuyerId")));
        }
        shipmentVo.setEbayOrderVo(ebayOrderVo);

        /**************************** shipment orderVo ***********************/
        if (json.containsKey("shipper")) {
            JSONObject shipper = (JSONObject) json.getJSONObject("shipper");
            if (shipper.containsKey("pickupAddressCode")) {
                shipmentVo.setPickupAddressCode(StringUtils.trim(shipper.getString("pickupAddressCode")));
            }
        }

        /**************************** shipment 定制化服务 ***********************/
        if (json.containsKey("serviceOptions")) {
            JSONObject serviceOptions = (JSONObject) json.getJSONObject("serviceOptions");
            if (serviceOptions.containsKey("isNeedSignature")) {
                shipmentVo.setIsNeedSignature(serviceOptions.getBoolean("isNeedSignature"));
            }
        }

        /**************************** shipment BuyerInfo ***********************/
        if (json.containsKey("receiver")) {
            JSONObject receiver = (JSONObject) json.getJSONObject("receiver");
            BuyerInfo originalBuyerInfo = new BuyerInfo();
            if (receiver.containsKey("receiverName")) {
                originalBuyerInfo.setBuyerName(StringUtils.trim(receiver.getString("receiverName")));
            }
            if (receiver.containsKey("phoneNo")) {
                originalBuyerInfo.setBuyerPhone(StringUtils.trim(receiver.getString("phoneNo")));
            }
            if (receiver.containsKey("email")) {
                originalBuyerInfo.setBuyerEmail(StringUtils.trim(receiver.getString("email")));
            }
            if (receiver.containsKey("postCode")) {
                originalBuyerInfo.setBuyerPostcode(StringUtils.trim(receiver.getString("postCode")));
            }
            if (receiver.containsKey("countryCode")) {
                originalBuyerInfo.setBuyerCountry(StringUtils.trim(receiver.getString("countryCode")));
            }
            if (receiver.containsKey("state")) {
                originalBuyerInfo.setBuyerState(StringUtils.trim(receiver.getString("state")));
            }
            if (receiver.containsKey("city")) {
                originalBuyerInfo.setBuyerCity(StringUtils.trim(receiver.getString("city")));
            }
            if (receiver.containsKey("addressLine1")) {
                originalBuyerInfo.setBuyerAddress1(StringUtils.trim(receiver.getString("addressLine1")));
            }
            if (receiver.containsKey("addressLine2")) {
                originalBuyerInfo.setBuyerAddress2(StringUtils.trim(receiver.getString("addressLine2")));
            }
            if (receiver.containsKey("houseNo")) {
                originalBuyerInfo.setBuyerHouseNo(StringUtils.trim(receiver.getString("houseNo")));
            }
            shipmentVo.setOriginalBuyerInfo(originalBuyerInfo);
        }

        /****************************** Shipment Parcel **************************/
        List<LMAShipmentOrderPackageVo> packageVoList = new ArrayList<LMAShipmentOrderPackageVo>();
        if (json.containsKey("parcelList")) {
            JSONArray packageList = json.getJSONArray("parcelList");
            for (Object obj : packageList) {
                JSONObject pack = (JSONObject) obj;
                LMAShipmentOrderPackageVo packageVo = new LMAShipmentOrderPackageVo();
                if (pack.containsKey("parcelDesc")) {
                    packageVo.setParcelDesc(StringUtils.trim(pack.getString("parcelDesc")));
                }
                if (pack.containsKey("parcelNo")) {
                    packageVo.setParcelNo(StringUtils.trim(pack.getString("parcelNo")));
                }
                if (pack.containsKey("weight")) {
                    packageVo.setWeight(pack.getBigDecimal("weight").setScale(4, BigDecimal.ROUND_HALF_UP));
                }
                if (pack.containsKey("length")) {
                    packageVo.setLength(pack.getBigDecimal("length").setScale(2, BigDecimal.ROUND_HALF_UP));
                }
                if (pack.containsKey("width")) {
                    packageVo.setWidth(pack.getBigDecimal("width").setScale(2, BigDecimal.ROUND_HALF_UP));
                }
                if (pack.containsKey("height")) {
                    packageVo.setHeight(pack.getBigDecimal("height").setScale(2, BigDecimal.ROUND_HALF_UP));
                }

                /****************************** Merchandise **************************/
                List<LMAShipmentOrderMerchandiseVo> merchandiseVoList = new ArrayList<LMAShipmentOrderMerchandiseVo>();
                if (pack.containsKey("merchandiseList")) {
                    JSONArray merlist = pack.getJSONArray("merchandiseList");
                    if (merlist != null) {
                        for (Object o : merlist) {
                            JSONObject mer = (JSONObject) o;
                            LMAShipmentOrderMerchandiseVo merchandiseVo = new LMAShipmentOrderMerchandiseVo();
                            if (mer.containsKey("eBayTransactionId")) {
                                merchandiseVo.seteBayTransactionId(StringUtils.trim(mer.getString("eBayTransactionId")));
                            }
                            if (mer.containsKey("eBayItemId")) {
                                merchandiseVo.seteBayItemId(StringUtils.trim(mer.getString("eBayItemId")));
                            }
                            if (mer.containsKey("merchandiseName")) {
                                merchandiseVo.setMerchandiseName(StringUtils.trim(mer.getString("merchandiseName")));
                            }
                            if (mer.containsKey("merchandiseCode")) {
                                merchandiseVo.setMerchandiseCode(mer.getString("merchandiseCode"));
                            }
                            if (mer.containsKey("specifications")) {
                                merchandiseVo.setSpecifications(mer.getString("specifications"));
                            }
                            if (mer.containsKey("isHasBattery")) {
                                merchandiseVo.setIsHasBattery(mer.getBoolean("isHasBattery"));
                            }
                            if (mer.containsKey("quantity")) {
                                merchandiseVo.setQuantity(mer.getInteger("quantity"));
                            }
                            if (mer.containsKey("salePrice")) {
                                merchandiseVo.setSalePrice(mer.getBigDecimal("salePrice") == null ? null : mer.getBigDecimal("salePrice")
                                    .setScale(4, BigDecimal.ROUND_HALF_UP));
                            }
                            if (mer.containsKey("saleCurrency")) {
                                merchandiseVo.setSaleCurrency(StringUtils.trim(mer.getString("saleCurrency")));
                            }
                            if (mer.containsKey("declaredValue")) {
                                merchandiseVo.setDeclaredValue(mer.getBigDecimal("declaredValue") == null ? null : mer.getBigDecimal("declaredValue")
                                    .setScale(4, BigDecimal.ROUND_HALF_UP));
                            }
                            if (mer.containsKey("declaredCurrency")) {
                                merchandiseVo.setDeclaredCurrency(StringUtils.trim(mer.getString("declaredCurrency")));
                            }
                            if (mer.containsKey("declaredNameCn")) {
                                merchandiseVo.setDeclaredNameCn(StringUtils.trim(mer.getString("declaredNameCn")));
                            }
                            if (mer.containsKey("declaredNameEn")) {
                                merchandiseVo.setDeclaredNameEn(StringUtils.trim(mer.getString("declaredNameEn")));
                            }
                            if (mer.containsKey("weight")) {
                                merchandiseVo.setWeight(mer.getBigDecimal("weight") == null ? null : mer.getBigDecimal("weight")
                                    .setScale(4, BigDecimal.ROUND_HALF_UP));
                            }
                            merchandiseVoList.add(merchandiseVo);
                        }
                    }
                }
                packageVo.setMerchandiseList(merchandiseVoList);
                packageVoList.add(packageVo);
            }
        }
        shipmentVo.setPackageList(packageVoList);

        CommandContext ctx = CommandContext.getContext();
        String source = (String) ctx.get(ApiConstant.API_SOURCE);
        shipmentVo.setOrganizationId(ctx.getOrgId());
        shipmentVo.setOrderSource(source);
        return shipmentVo;
    }

    /**
     * 构建卖家网站查询的接口信息
     * 
     * @param json
     * @return
     */
    public static QueryShipmentOrderBySellerCommand buildQueryShipmentOrderBySeller(JSONObject json) {
        LMAShipmentOrderSellerQueryVo queryVo = new LMAShipmentOrderSellerQueryVo();

        QueryShipmentOrderBySellerCommand command = new QueryShipmentOrderBySellerCommand();
        if (json.containsKey("merchandiseCode")) {// 订单号
            queryVo.setMerchandiseCode(json.getString("merchandiseCode"));
        }
        if (json.containsKey("orderDateFrom")) {// winit跟踪号
            String orderDateStart = json.getString("orderDateFrom");
            orderDateStart += " 00:00:00";
            Date from = DateUtil.parse2Date(orderDateStart, DateUtil.FULL_DATE_STRING);
            queryVo.setOrderDateFrom(from);
        }
        if (json.containsKey("orderDateTo")) {// 结束时间
            String orderDateEnd = json.getString("orderDateTo");
            orderDateEnd += " 23:59:59";
            Date end = DateUtil.parse2Date(orderDateEnd, DateUtil.FULL_DATE_STRING);
            queryVo.setOrderDateTo(end);
        }
        if (json.containsKey("winitOrderNos")) {
            JSONArray arr = json.getJSONArray("winitOrderNos");
            List<String> orderNos = new ArrayList<String>();
            for (int i = 0; i < arr.size(); i++) {
                String orderNo = arr.getString(i);
                orderNos.add(orderNo);
            }
            queryVo.setOrderNos(orderNos);
        }
        if (json.containsKey("orderStatus")) {
            queryVo.setOrderStatus(json.getString("orderStatus"));
        }
        if (json.containsKey("sellerOrderNo")) {
            queryVo.setSellerOrderNo(json.getString("sellerOrderNo"));
        }
        if (json.containsKey("trackingNo")) {
            queryVo.setTrackingNo(json.getString("trackingNo"));
        }
        if (json.containsKey("winitProductCode")) {
            queryVo.setWinitProductCode(json.getString("winitProductCode"));
        }
        command.setQueryVo(queryVo);
        return command;
    }

    /**
     * 返回卖家网站列表页面查询的信息
     * 
     * @param vos
     * @return
     */
    public static List<Map<String, Object>> buildGetOrderListBySeller(List<LMAShipmentOrderVo> vos) {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (LMAShipmentOrderVo vo : vos) {
            list.add(buildShipmentOrderListPageVo(vo));
        }
        return list;
    }

    public static Map<String, Object> buildShipmentOrderListPageVo(LMAShipmentOrderVo vo) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("orderNo", vo.getOrderNo());// 订单编号.
        map.put("sellerOrderNo", vo.getSellerOrderNo());// 卖家订单号
        map.put("status", vo.getStatus());// 订单状态
        map.put("orderTime", vo.getOrderTime());// 下单时间(订单创建时间)
        map.put("totalParcelsVolume", vo.getTotalParcelsVolume());
        map.put("totalParcelsWeight", vo.getTotalParcelsWeight());
        map.put("trackingNo", "");
        map.put("customerName", vo.getCustomerInfo().getCustomerName());
        map.put("cancelReason", vo.getCancelReason());
        List<LMAShipmentOrderLabelVo> labels = vo.getLabelList();
        if (labels != null && labels.size() > 0) {
            map.put("trackingNo", labels.get(0).getTrackingNo());
        }

        // 收件人信息
        BuyerInfo buyerInfo = vo.getBuyerInfoVo();
        if (buyerInfo != null) {
            Map<String, Object> receiver = new HashMap<String, Object>();
            receiver.put("state", buyerInfo.getBuyerState());
            receiver.put("city", buyerInfo.getBuyerCity());
            receiver.put("postCode", buyerInfo.getBuyerPostcode());
            receiver.put("receiverName", buyerInfo.getBuyerName());
            receiver.put("countryCode", buyerInfo.getBuyerCountry());
            map.put("receiver", receiver);
        }
        Map<String, Object> shipper = new HashMap<String, Object>();
        shipper.put("pickupAddressCode", vo.getPickupAddressCode());
        shipper.put("pickupAddressName", vo.getPickupAddressName());
        map.put("shipper", shipper);

        // 产品信息
        ProductInfo productInfo = vo.getProductInfo();
        if (productInfo != null) {
            map.put("winitProductCode", productInfo.getWinitProductCode());
            map.put("winitProductName", productInfo.getWinitProductName());// Winit产品名称
        }
        return map;
    }

    /**
     * 返回卖家网站列表页面查询的信息
     * 
     * @param vos
     * @return
     */
    public static Map<String, Object> buildOrderDetailListByOrderNo(LMAShipmentOrderVo vo) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("orderNo", vo.getOrderNo());// 订单编号.
        map.put("sellerOrderNo", vo.getSellerOrderNo());// 卖家订单号
        map.put("eBayOrderId", vo.getEbayOrderVo() == null ? "" : vo.getEbayOrderVo().getEbayOrderNo());
        map.put("eBaySellerId", vo.getEbayOrderVo() == null ? "" : vo.getEbayOrderVo().getEbaySellerId());
        map.put("eBayBuyerId", vo.getEbayOrderVo() == null ? "" : vo.getEbayOrderVo().getEbayBuyerId());
        map.put("status", vo.getStatus());// 订单状态
        map.put("orderTime", vo.getOrderTime());// 下单时间(订单创建时间)
        map.put("totalParcelsVolume", vo.getTotalParcelsVolume());
        map.put("totalParcelsWeight", vo.getTotalParcelsWeight());
        map.put("shiperMemo", vo.getShiperMemo());
        map.put("trackingNo", "");
        map.put("customerName", vo.getCustomerInfo().getCustomerName());
        map.put("totalParcelsNumber", vo.getTotalParcelsNumber());
        map.put("isNeedSignature", vo.getIsNeedSignature());
        map.put("cancelReason", vo.getCancelReason());
        List<LMAShipmentOrderLabelVo> labels = vo.getLabelList();
        if (labels != null && labels.size() > 0) {
            map.put("trackingNo", labels.get(0).getTrackingNo());
        }
        // 收件人信息
        BuyerInfo buyerInfo = vo.getBuyerInfoVo();
        if (buyerInfo != null) {
            Map<String, Object> receiver = new HashMap<String, Object>();
            receiver.put("state", buyerInfo.getBuyerState());
            receiver.put("city", buyerInfo.getBuyerCity());
            receiver.put("postCode", buyerInfo.getBuyerPostcode());
            receiver.put("receiverName", buyerInfo.getBuyerName());
            receiver.put("countryCode", buyerInfo.getBuyerCountry());
            receiver.put("phoneNo", buyerInfo.getBuyerPhone());
            receiver.put("email", buyerInfo.getBuyerEmail());
            receiver.put("addressLine1", buyerInfo.getBuyerAddress1());
            receiver.put("addressLine2", buyerInfo.getBuyerAddress2());
            receiver.put("houseNo", buyerInfo.getBuyerHouseNo());
            map.put("receiver", receiver);
        }
        Map<String, Object> shipper = new HashMap<String, Object>();
        shipper.put("pickupAddressCode", vo.getPickupAddressCode());
        shipper.put("pickupAddressName", vo.getPickupAddressName());
        map.put("shipper", shipper);

        // 产品信息
        ProductInfo productInfo = vo.getProductInfo();
        if (productInfo != null) {
            map.put("winitProductCode", productInfo.getWinitProductCode());
            map.put("winitProductName", productInfo.getWinitProductName());// Winit产品名称
        }

        List<LMAShipmentOrderPackageVo> pkgVos = vo.getPackageList();
        if (pkgVos != null && pkgVos.size() > 0) {
            List<Map<String, Object>> pkgList = new ArrayList<Map<String, Object>>();
            for (LMAShipmentOrderPackageVo pkgVo : pkgVos) {
                Map<String, Object> pkgMap = new HashMap<String, Object>();
                pkgMap.put("parcelDesc", pkgVo.getParcelDesc());
                pkgMap.put("parcelNo", pkgVo.getParcelNo());
                pkgMap.put("weight", pkgVo.getWeight());
                pkgMap.put("length", pkgVo.getLength());
                pkgMap.put("width", pkgVo.getWidth());
                pkgMap.put("height", pkgVo.getHeight());
                pkgList.add(pkgMap);

                List<Map<String, Object>> merList = new ArrayList<Map<String, Object>>();
                List<LMAShipmentOrderMerchandiseVo> merVos = pkgVo.getMerchandiseList();
                if (merVos != null && merVos.size() > 0) {
                    for (LMAShipmentOrderMerchandiseVo merVo : merVos) {
                        Map<String, Object> merMap = new HashMap<String, Object>();
                        merMap.put("eBayTransactionId", merVo.geteBayTransactionId());
                        merMap.put("eBayItemId", merVo.geteBayItemId());
                        merMap.put("merchandiseName", merVo.getMerchandiseName());
                        merMap.put("merchandiseCode", merVo.getMerchandiseCode());
                        merMap.put("isHasBattery", merVo.getIsHasBattery());
                        merMap.put("quantity", merVo.getQuantity());
                        merMap.put("specifications", merVo.getSpecifications());
                        merMap.put("salePrice", merVo.getSalePrice());
                        merMap.put("saleCurrency", merVo.getSaleCurrency());
                        merMap.put("declaredValue", merVo.getDeclaredValue());
                        merMap.put("declaredCurrency", merVo.getDeclaredCurrency());
                        merMap.put("declaredNameCn", merVo.getDeclaredNameCn());
                        merMap.put("declaredNameEn", merVo.getDeclaredNameEn());
                        merList.add(merMap);
                    }
                }
                pkgMap.put("merchandiseList", merList);
            }
            map.put("parcelList", pkgList);
        }
        return map;
    }

    public static List<Map<String, Object>> buildExportOrderListBySeller(List<LMAShipmentOrderVo> vos) {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (LMAShipmentOrderVo vo : vos) {
            list.add(buildOrderDetailListByOrderNo(vo));
        }
        return list;
    }

    public static Map<String, Object> buildReturnLmaOrderInfoByWorkOrder(LMAShipmentOrderWorkOrderHelpVo vo) {
        Map<String, Object> map = new HashMap<String, Object>();
        if(null != vo){
            map.put("orderNo", convertValue(vo.getOrderNo()) );// 订单编号
            map.put("status", convertValue(vo.getStatus()));// 订单状态
            map.put("trackingNo", convertValue(vo.getTrackingNo()));// 挂号
            map.put("isAllowClaim",convertValue(vo.getIsAllowClaim())); // 是否支持索赔
            map.put("dispatchVendorCode", convertValue(vo.getDispatchVendorCode())); // 供应商编码
            map.put("dispatchVendorName", convertValue(vo.getDispatchVendorName()));// 供应商编码
            map.put("dispatchType", convertValue(vo.getDispatchType()));// 派送方式
            map.put("whCurrencyCode", convertValue(vo.getWhCurrencyCode()));// 仓库币种
            map.put("merchandiseQTY", convertValue(vo.getMerchandiseQTY()));// 商品数量
            map.put("customerCode", convertValue(vo.getCustomerCode()));// 客户编码
            map.put("customerName", convertValue(vo.getCustomerName())); // 客户名称
            map.put("warehouseName", convertValue(vo.getWarehouseName())); // 仓库名称
            map.put("deliveryAmount", convertValue(vo.getDeliveryAmount()));// 派送费
            map.put("vendorCode", convertValue(vo.getVendorCode()));// 供应商编码
            map.put("vendorName", convertValue(vo.getVendorName()));// 供应商名称
            map.put("warehouseCode", convertValue(vo.getWarehouseCode()));// 仓库编码
            map.put("productCode", convertValue(vo.getProductCode()));// 产品编码
        }
        return map;
    }
    
    /**
     * 将null转换为空字符串或默认值
     * @param object
     * @return
     */
    protected static Object convertValue(Object object){
        if(object instanceof String){
            return ObjectUtils.toString(object) ;
        }else if(object instanceof Integer){
            return object == null ? 0 : object ;
        }else if(object instanceof BigDecimal){
            return object == null ? BigDecimal.ZERO : object ;
        }else{
            return "";
        }
    }
    
}
